package com.xh.bussiness.tiku.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xh.bussiness.system.model.Area;
import com.xh.bussiness.system.model.Dictionary;
import com.xh.bussiness.system.service.IAreaService;
import com.xh.bussiness.system.service.IDictionaryService;
import com.xh.bussiness.tiku.bean.dto.QuestionDto;
import com.xh.bussiness.tiku.constant.QuestionConstant;
import com.xh.bussiness.tiku.model.*;
import com.xh.bussiness.tiku.service.IBookChapterService;
import com.xh.bussiness.tiku.service.IKnowledgeService;
import com.xh.bussiness.tiku.service.IQuestionTypeRelationService;
import com.xh.bussiness.xkw.model.PropertyPriority;
import com.xh.bussiness.xkw.model.XkwQuestion;
import com.xh.bussiness.xkw.model.XkwSubject;
import com.xh.bussiness.xkw.service.IXkwSubjectService;
import com.xh.core.util.RegexUtils;
import com.xh.core.util.StringUtils;
import com.xh.tools.question.constant.QuestionTypeEnum;
import com.xh.tools.question.data.dto.QuestionDTO;
import com.xh.tools.question.util.QuestionUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.regex.Matcher;
import java.util.stream.Collectors;

@Component
public class QuestionConverUtils {

    static Map<String, Integer> difficultMap = new HashMap<>();

    static {
        difficultMap.put("容易", 11);
        difficultMap.put("较易", 12);
        difficultMap.put("一般", 13);
        difficultMap.put("较难", 14);
        difficultMap.put("困难", 15);
    }

    private static IXkwSubjectService _xkwSubjectService;
    private static IDictionaryService _dictionaryService;
    private static IKnowledgeService _knowledgeService;
    private static IBookChapterService _bookChapterService;
    private static IQuestionTypeRelationService _relationService;
    private static IAreaService _areaService;

    @Autowired
    private IXkwSubjectService xkwSubjectService;
    @Autowired
    private IDictionaryService dictionaryService;
    @Autowired
    private IKnowledgeService knowledgeService;
    @Autowired
    private IBookChapterService bookChapterService;
    @Autowired
    private IQuestionTypeRelationService relationService;
    @Autowired
    private IAreaService areaService;

    @PostConstruct
    public void init() {
        _xkwSubjectService = xkwSubjectService;
        _dictionaryService = dictionaryService;
        _knowledgeService = knowledgeService;
        _bookChapterService = bookChapterService;
        _relationService = relationService;
        _areaService = areaService;
    }

    public static void main(String[] args) {
        String typeName = "湖南省郴州市2020-2021学年高一上学期期末教学质量监测英语试题";
        Matcher matcher = RegexUtils.getMatcher(typeName, "[\\u4e00-\\u9fa5]*省");
        if (matcher.find()) {
            System.out.println(matcher.group());
        }
        System.out.println();
    }

    public static QuestionDto xkwQuestion2MyQuestion(XkwQuestion xkwQuestion) {
        Map<String, Object> typeMap = xkwQuestion.getQuesType();
        String typeName;
        if (typeMap != null) {
            typeName = MapUtils.getString(typeMap, "name");
        }else{
            typeName = QuestionTypeEnum.OTHER.getText();
        }
        QuestionDto question = new QuestionDto();
        String difficultName = xkwQuestion.getQuesDiff() == null ? null : xkwQuestion.getQuesDiff().getName();
        // 难度
        question.setDifficult(difficultMap.get(difficultName));
        // 解析
//        question.setAnalysis(xkwQuestion.getQuesParse() == null ? "" : xkwQuestion.getQuesParse().substring(4));
        question.setAnalysis(StringUtils.isEmpty(xkwQuestion.getQuesParse()) ? "" : xkwQuestion.getQuesParse());
        // 学科网学科id
        question.setXkwSubjectId(xkwQuestion.getSubjectId());
        // 年级
        List<Map> grades = xkwQuestion.getGrades();
        question.setGradeId(CollectionUtils.isEmpty(grades) ? null : MapUtils.getString(grades.get(0), "name"));
        // 类型
        List<PropertyPriority> sources = xkwQuestion.getPaperTypes();
        question.setCategory(CollectionUtils.isEmpty(sources) ? null : sources.get(0).getName());
        String title = xkwQuestion.getTitle();
        // 年份
        Matcher matcher = RegexUtils.getMatcher(title, "\\d{4}");
        if (matcher.find()) {
            question.setYear(matcher.group());
        }
        // 知识点
        List<List<PropertyPriority>> allKnowledge = xkwQuestion.getCategories();
        for (List<PropertyPriority> knowledges : allKnowledge) {
            question.setKnowledgePoints(knowledges.stream().map(PropertyPriority::getName).collect(Collectors.toList()));
        }
        // 章节
        List<List<PropertyPriority>> allChapter = xkwQuestion.getCategories();
        for (List<PropertyPriority> chapters : allChapter) {
            question.setChaptersIds(chapters.stream().map(PropertyPriority::getName).collect(Collectors.toList()));
        }

        // 省份
        matcher = RegexUtils.getMatcher(title, "[\\u4e00-\\u9fa5]*省|内蒙古自治区|广西壮族自治区|西藏自治区|宁夏回族自治区|新疆维吾尔自治区|北京市|天津市|上海市|重庆市");
        if (matcher.find()) {
            question.setProviceId(matcher.group());
        }
        // 市
        matcher = RegexUtils.getMatcher(title, "[\\u4e00-\\u9fa5]*市");
        if (matcher.find()) {
            String city = matcher.group();
            if (!RegexUtils.Match(city, "北京市|天津市|上海市|重庆市")) {
                question.setProviceId(city);
            }
        }
        // 选择题  或者 其他题型里有选项的暂时按选择题处理
        System.out.println("typeName:  "+typeName);
        if (RegexUtils.Match(typeName, "单选题|选择题|单项选择|单项选择题|多选题|不定项选择|七选五|六选四|五选五")){
//        || (xkwQuestion.getQuesBody().contains("<table") && xkwQuestion.getQuesBody().contains("name=\"optionsTable\""))) {//
           createChooseQuestion(xkwQuestion, question);
            System.out.println("typeName: 【"+typeName+"】，走了选择题逻辑");
        }else if (RegexUtils.Match(typeName, "判断题")) {
            //判断题
            createJudgeQuestion(xkwQuestion, question);
            System.out.println("typeName: 【"+typeName+"】，走了判断题逻辑");
        }else if (RegexUtils.Match(typeName, "完形填空|完型填空")) {
            // 完形填空
            createCloneQuestion(xkwQuestion, question);
            System.out.println("typeName: 【"+typeName+"】，走了完形填空逻辑");
        }else if (RegexUtils.Match(typeName, "阅读理解|现代文阅读|阅读题型|文言文阅读|古诗歌阅读|诗歌鉴赏|阅读单选|阅读判断")) {
            // 阅读理解
           createReadingQuestion(xkwQuestion, question);
            System.out.println("typeName: 【"+typeName+"】，走了阅读理解逻辑");
        }else{
            createEssayQuestion(xkwQuestion, question);
        }
        Integer xkwSubjectId = question.getXkwSubjectId();
        //查询学科
        if (xkwSubjectId != null) {
            QueryWrapper<XkwSubject> queryWrapper = new QueryWrapper();
            queryWrapper.eq("xkw_id", xkwSubjectId);
            XkwSubject subject = _xkwSubjectService.selectFirst(queryWrapper);
//            String subjectName = subject.getName();
            String subjectName = null;
            if(subject!=null){
                subjectName = subject.getName();
            }
            com.xh.bussiness.system.model.Dictionary dictionary = _dictionaryService.queryFirstByName("SUBJECT", subjectName);
            if (dictionary != null) {
                question.setSubjectId(dictionary.getCode());
            } else {
                // TODO: 考虑新建学科
            }
        }
        String subjectId = question.getSubjectId();
        if (!StringUtils.isEmpty(subjectId)) {
            String questionTypeName = MapUtils.getString(typeMap, "name");
            if (question.getBasicQuestionType() == 1 || question.getBasicQuestionType() == 2 || question.getBasicQuestionType() == 3 || question.getBasicQuestionType() == 10) {
                // 查询jy题型 根据 questionDto.getBasicQuestionType()
                if (question.getBasicQuestionType().equals(1)) {
                    question.setType(1);
                } else {
                    QueryWrapper qw = new QueryWrapper();
                    qw.eq("tool_question_type", question.getBasicQuestionType());
                    //查询基础题型
//                    qw.eq("need_match", 0);
                    qw.eq("subject_id", subjectId);

                    QuestionTypeRelation relation = (QuestionTypeRelation) _relationService.selectFirst(qw);
                    if (relation != null) {
                        question.setType(relation.getJyQuestionType());
                        question.setQuestionTypeName(relation.getJyQuestionTypeName());
                    } else {
                        question.setType(888);
                        question.setQuestionTypeName("其他");
                    }
                }
            } else {
                // 查询jy题型 根据 typeName
                if (!StringUtils.isEmpty(questionTypeName)) {
                    QueryWrapper qw = new QueryWrapper();
                    qw.eq("jy_question_type_name", questionTypeName);
                    qw.eq("subject_id", subjectId);

                    QuestionTypeRelation relation = (QuestionTypeRelation) _relationService.selectFirst(qw);
                    if (relation != null) {
                        question.setType(relation.getJyQuestionType());
                    } else {
                        question.setType(888);
                    }
                } else {
                    //其他题型
                    question.setType(888);
                }
            }
        }
        // 年级
        String gradeName = question.getGradeId();
        com.xh.bussiness.system.model.Dictionary grade = _dictionaryService.queryFirstByName("GRADE", gradeName);
        if (grade != null) {
            question.setGradeId(grade.getId());
        }
        // 年份
        com.xh.bussiness.system.model.Dictionary year = _dictionaryService.queryFirstByName("YEAR", question.getYear());
        if (year != null) {
            question.setYear(year.getId());
        }
        // 知识点
        List<String> knowledgeNames = question.getKnowledgePoints();
        if (CollectionUtils.isNotEmpty(knowledgeNames)) {
            QueryWrapper<Knowledge> qw = new QueryWrapper<>();
            qw.in("name", knowledgeNames);
            List<Knowledge> knowledges = _knowledgeService.queryByCondition(qw);
            question.setKnowledges(knowledges);
        }

        // 章节
        List<String> chapterNames = question.getChaptersIds();
        if (CollectionUtils.isNotEmpty(chapterNames)) {
            QueryWrapper<BookChapter> bcqw = new QueryWrapper<>();
            bcqw.in("name", chapterNames);
            List<BookChapter> bookChapters = _bookChapterService.queryByCondition(bcqw);
            question.setChaptersIds(bookChapters.stream().map(BookChapter::getId).collect(Collectors.toList()));
        }
        // 类型
        Dictionary category = _dictionaryService.queryFirstByName("QUES_SOURCE", question.getYear());
        if (category != null) {
            question.setCategory(category.getId());
        }
        // 来源：省 市 区 类型 公立校
        if (StringUtils.isNotEmpty(question.getProviceId())) {
            QueryWrapper<Area> areaQw = new QueryWrapper<>();
            areaQw.eq("name", question.getProviceId());
            areaQw.eq("parent_id", null);
            Area province = _areaService.selectFirst(areaQw);
            List<QuestionSource> questionSources = new ArrayList<>();
            QuestionSource questionSource = new QuestionSource();
            if (province != null) {
                questionSource.setProvinceId(province.getId());
                questionSource.setProvinceName(province.getName());
                questionSources.add(questionSource);
                question.setQuestionSources(questionSources);

                areaQw = new QueryWrapper<>();
                areaQw.eq("name", question.getCityId());
                areaQw.eq("parent_id", province.getId());
                Area city = _areaService.selectFirst(areaQw);
                if (city != null) {
                    questionSource.setCityId(city.getId());
                    questionSource.setCityName(city.getName());
                }
            }
            questionSource.setDictSourceId(question.getCategory());
            questionSource.setYear(question.getYear());
        }
        return question;
    }

    /**
     * 单选题、多选题、不定项选择题（七选五）
     *
     * @param xkwQuestion
     * @return
     */
    public static QuestionDto createChooseQuestion(XkwQuestion xkwQuestion, QuestionDto question) {
        String title = getTitle(xkwQuestion.getQuesBody());
        String quesBody = xkwQuestion.getQuesBody();

        // 题型
        Map<String, Object> typeMap = xkwQuestion.getQuesType();
        String typeName = MapUtils.getString(typeMap, "name");
        if ("单项选择".equals(typeName) || "选择题".equals(typeName) || "单选题".equals(typeName) || "单项选择题".equals(typeName) || "单项选择".equals(typeName)) {
            question.setBasicQuestionType(QuestionTypeEnum.SINGLE.getValue());
            question.setBasicQuestionTypeName("单选题");
        } else {
            question.setBasicQuestionType(QuestionTypeEnum.MUL.getValue());
            question.setBasicQuestionTypeName("多选题");
        }

        if (quesBody.contains("<table name=\"optionsTable\"")) {
            String optionTable = quesBody.substring(quesBody.indexOf("<table name=\"optionsTable\""));
            Document document = Jsoup.parse(optionTable);
            List<Element> tds = document.getElementsByTag("td");
            JSONArray options = new JSONArray();
            for (Element td : tds) {
                JSONObject option = new JSONObject();
                String optionStr = td.html();
                Matcher matcher = RegexUtils.getMatcher(optionStr, QuestionConstant.REGEX_MATCH_RULE.XKW_OPTION_START_TAG);
                if (matcher.find()) {
                    String index = matcher.group();
                    option.put("name", index.substring(0, 1));
                    option.put("no", QuestionConstant.OPTION_ORDER.indexOf(index.substring(0, 1)) + 1);
                    option.put("content", optionStr.substring(index.length()));
                    options.add(option);
                }
            }
            question.setTitle(title);
            question.setOption(options);
            String answerStr = xkwQuestion.getQuesAnswer();
            Matcher matcher = RegexUtils.getMatcher(answerStr, "[A-Z]");
            while (matcher.find()) {
                String name = matcher.group();
                JSONObject answer = new JSONObject();
                answer.put("name", name);
                answer.put("no", QuestionConstant.OPTION_ORDER.indexOf(name) + 1);
                answer.put("content", name);
                JSONArray answers = new JSONArray();
                answers.add(answer);
                question.setRightAnswer(answers);
            }
        } else {
            QuestionDTO parse = QuestionUtils.parse(question.getBasicQuestionType(), question.getBasicQuestionTypeName(), quesBody, xkwQuestion.getQuesAnswer(), "");
            question.setTitle(parse.getTitle());
            question.setOption(CollectionUtils.isEmpty(parse.getOptionList()) ? null : (JSON) JSON.toJSON(parse.getOptionList()));
            question.setRightAnswer(CollectionUtils.isEmpty(parse.getRightAnswerList()) ? null : (JSON) JSON.toJSON(parse.getRightAnswerList()));
        }
        return question;
    }

    /**
     * 判断题
     *
     * @param xkwQuestion
     * @return
     */
    public static QuestionDto createJudgeQuestion(XkwQuestion xkwQuestion, QuestionDto question) {
        String title = getTitle(xkwQuestion.getQuesBody());
        question.setTitle(title);

        String quesAnswer = xkwQuestion.getQuesAnswer();
        if (!StringUtils.isEmpty(quesAnswer)) {
            JSONObject answer = new JSONObject();
            answer.put("no", 1);
            answer.put("content", quesAnswer.replaceAll("【答案】", ""));
            JSONArray answers = new JSONArray();
            answers.add(answer);
            question.setRightAnswer(answers);
        }
        question.setBasicQuestionType(QuestionTypeEnum.JUDGE.getValue());
        question.setBasicQuestionTypeName(QuestionTypeEnum.JUDGE.getText());
        return question;
    }

    /**
     * 完形填空
     *
     * @param xkwQuestion
     * @return
     */
    public static QuestionDto createCloneQuestion(XkwQuestion xkwQuestion, QuestionDto question) {
        String title = getTitle(xkwQuestion.getQuesBody());
        String quesBody = xkwQuestion.getQuesBody();
//        if (quesBody.contains("<table cellpadding=\"0\"")) {
//            String optionTable = quesBody.substring(quesBody.indexOf("<table cellpadding=\"0\""));
            Document document = Jsoup.parse(quesBody);
            List<Element> optionTables = document.getElementsByAttributeValue("name", "optionsTable");
            System.out.println("optionTables：" + optionTables.size());
            JSONArray options = new JSONArray();
            Integer index = 0;
            for (Element table : optionTables) {
                System.out.println("table："+table.toString());
                index++;
                JSONObject option = new JSONObject();
                option.put("name", String.valueOf(index));
                List<Element> tds = table.getElementsByTag("td");
                JSONArray childs = new JSONArray();
                for (Element td : tds) {
                    JSONObject child = new JSONObject();
                    String optionStr = td.text();
                    Matcher matcher = RegexUtils.getMatcher(optionStr, QuestionConstant.REGEX_MATCH_RULE.XKW_OPTION_START_TAG);
                    if (matcher.find()) {
                        String optionStart = matcher.group();
                        child.put("name", optionStart.substring(0, 1));
                        child.put("no", QuestionConstant.OPTION_ORDER.indexOf(optionStart.substring(0, 1)) + 1);
                        child.put("content", optionStr.substring(optionStart.length()));
                        childs.add(child);
                    }
                }
                option.put("childs", childs);
                options.add(option);
            }
            System.out.println("options：   "+JSON.toJSONString(options));
            question.setOption(options);
//        }
        question.setTitle(title);
        String answerStr = xkwQuestion.getQuesAnswer();
        Matcher matcher = RegexUtils.getMatcher(answerStr, "[A-Z]");
        JSONArray answers = new JSONArray();
        while (matcher.find()) {
            String name = matcher.group();
            JSONObject answer = new JSONObject();
            answer.put("name", name);
            answer.put("no", QuestionConstant.OPTION_ORDER.indexOf(name) + 1);
            answer.put("content", name);
            answers.add(answer);
        }
        question.setRightAnswer(answers);
        question.setBasicQuestionType(QuestionTypeEnum.CLOZE.getValue());
        question.setBasicQuestionTypeName("完形填空");
        System.out.println();
        return question;
    }

    /**
     * 完形填空
     *
     * @param xkwQuestion
     * @return
     */
    public static QuestionDto createReadingQuestion(XkwQuestion xkwQuestion, QuestionDto question) {
        String quesBody = xkwQuestion.getQuesBody();
        if (RegexUtils.Match(quesBody, "【小题\\d】")) {
            String title = quesBody.substring(0, quesBody.indexOf("【小题1】"));
            String subQuestion = quesBody.substring(quesBody.indexOf("【小题1】"));
            List<String> htmls = Arrays.asList(subQuestion.split("【小题\\d】"));
            List<QuestionDto> childs = new ArrayList<>();
            for (String html : htmls) {
                if (StringUtils.isEmpty(html)) {
                    continue;
                }
                String subTitle;
                if (html.contains("<table name=\"optionsTable\"")) {
                    subTitle = html.substring(0, html.indexOf("<table name=\"optionsTable\"")).replace("【小题\\d】", "");
                } else {
                    subTitle = html;
                }
                QuestionDto child = new QuestionDto();
                child.setTitle(subTitle);
                if (html.contains("<table name=\"optionsTable\"")) {
                    Document document = Jsoup.parse(html);
                    Element table = document.getElementsByAttributeValue("name", "optionsTable").get(0);
                    List<Element> tds = table.getElementsByTag("td");
                    JSONArray options = new JSONArray();
                    for (Element td : tds) {
                        JSONObject option = new JSONObject();
                        String optionStr = td.text();
                        Matcher matcher = RegexUtils.getMatcher(optionStr, QuestionConstant.REGEX_MATCH_RULE.XKW_OPTION_START_TAG);
                        if (matcher.find()) {
                            String index = matcher.group();
                            option.put("name", index.substring(0, 1));
                            option.put("no", QuestionConstant.OPTION_ORDER.indexOf(index.substring(0, 1)) + 1);
                            option.put("content", optionStr.substring(index.length()));
                            options.add(option);
                        }
                    }
                    child.setOption(options);
                }
                childs.add(child);
                question.setChilds(childs);
            }
            question.setTitle(getTitle(title));
        }else{
            //没有小题的情况
            question.setTitle(getTitle(quesBody));
        }
        String answerStr = xkwQuestion.getQuesAnswer();
        Matcher matcher = RegexUtils.getMatcher(answerStr, "[A-Z]");
        JSONArray answers = new JSONArray();
        while (matcher.find()) {
            String name = matcher.group();
            JSONObject answer = new JSONObject();
            answer.put("name", name);
            answer.put("no", QuestionConstant.OPTION_ORDER.indexOf(name) + 1);
            answer.put("content", name);
            answers.add(answer);
        }
        question.setRightAnswer(answers);
        question.setBasicQuestionType(QuestionTypeEnum.READING.getValue());
        question.setBasicQuestionTypeName("阅读理解");
        return question;
    }

    /**
     * @param xkwQuestion
     * @return
     */
    public static QuestionDto createEssayQuestion(XkwQuestion xkwQuestion, QuestionDto question) {
        String title = getTitle(xkwQuestion.getQuesBody());
        question.setTitle(title);
//        String answerContent = xkwQuestion.getQuesAnswer() == null ? "" : xkwQuestion.getQuesAnswer().substring(4);
        String answerContent = StringUtils.isEmpty(xkwQuestion.getQuesAnswer())? "" : xkwQuestion.getQuesAnswer();
        JSONObject answer = new JSONObject();
        answer.put("name", answerContent);
        answer.put("no", 1);
        answer.put("content", answerContent);
        JSONArray answers = new JSONArray();
        answers.add(answer);
        question.setRightAnswer(answers);
//        question.setAnalysis(xkwQuestion.getQuesParse() == null ? "" : xkwQuestion.getQuesParse().substring(4));
        question.setAnalysis( StringUtils.isEmpty(xkwQuestion.getQuesParse()) ? "" : xkwQuestion.getQuesParse());
        question.setBasicQuestionType(QuestionTypeEnum.ESSAY.getValue());
        question.setBasicQuestionTypeName("解答题");
        return question;
    }

    /**
     * 获取题目题干
     *
     * @param quesBody
     * @return
     */
    private static String getTitle(String quesBody) {
        if (StringUtils.isEmpty(quesBody)) {
            return quesBody;
        }
        if (quesBody.indexOf("<table cellpadding=\"0\"") > -1) {
            return quesBody.substring(0, quesBody.indexOf("<table cellpadding=\"0\"")).replace("【题文】", "");
        } else if (quesBody.indexOf("<table name=\"optionsTable\"") > -1) {
            return quesBody.substring(0, quesBody.indexOf("<table name=\"optionsTable\"")).replace("【题文】", "");
        } else {
            return quesBody.replace("【题文】", "");
        }
    }


}
